package com.tianyuan.lims.common.interceptor;

import cn.hutool.core.convert.BasicType;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Record;
import com.tianyuan.lims.common.annotation.HttpEnum;
import com.tianyuan.lims.common.annotation.NotNullValidate;
import com.tianyuan.lims.common.annotation.RequestBody;
import com.tianyuan.lims.common.config.redis.Redis;
import com.tianyuan.lims.common.config.redis.RedisManager;
import com.tianyuan.lims.erp.admin.entity.AdminUser;
import com.tianyuan.lims.utils.BaseUtil;
import com.tianyuan.lims.utils.R;
import com.tianyuan.lims.utils.RequestHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Parameter;
import java.util.Date;

public class ErpInterceptor implements Interceptor {

    private static Logger LOGGER = LoggerFactory.getLogger(ErpInterceptor.class);
    @Override
    public void intercept(Invocation invocation) {
        try {
            //TODO 临时取消登录验证
            Controller controller = invocation.getController();
            String token = BaseUtil.getToken(controller.getRequest());
            Object sessionToken = controller.getSessionAttr("token");
            sessionToken = sessionToken == null ? "" : sessionToken;
            if (StringUtils.isEmpty(token) && StringUtils.isNotEmpty(sessionToken.toString())) {
                token = (String) sessionToken;
            }
            AdminUser adminUser;
            Redis redis = RedisManager.getRedis();
            boolean enableRedis = redis == null ? false : true;
            if (enableRedis) {
                adminUser = redis.get(token);
            } else {
                adminUser = controller.getSessionAttr("user");
            }

            // 存储当前请求
            RequestHolder.setRequest(controller.getRequest());

            String uri = controller.getRequest().getRequestURI();
            if ( uri.contains("/app/")
                    || uri.contains("/api/")
                    || uri.contains("/captcha/")
                    || uri.contains("/apiLogin/")

                    //|| uri.contains("/")

                    || uri.contains("/limsCategory")

                    || uri.contains("/lims")



            ) { //
                invocation.invoke();
                return;
            }


            LOGGER.error("enableRedis: " + enableRedis +", adminUser:{}", adminUser);

            if (adminUser == null) {
                controller.renderJson(R.error(302, "请先登录！"));
                controller.getResponse().setStatus(302);
                return;
            }
            BaseUtil.setUser(adminUser);


            //数据非空验证
            if (!this.notNullValidate(invocation)) {
                return;
            }
            //数据转换json的处理
            this.modelToJson(invocation);
            if (enableRedis) {
                BaseUtil.userExpire(token);
            }
            invocation.invoke();
        } catch (Exception e) {
            invocation.getController().renderJson(R.error("服务器响应异常"));
            Log.getLog(invocation.getController().getClass()).error("响应错误", e);
        } finally {
            BaseUtil.removeThreadLocal();
            RequestHolder.removeRequest();
        }

    }

    /**
     * 数据非空校验
     */
    private boolean notNullValidate(Invocation inv) {
        NotNullValidate[] validates = inv.getMethod().getAnnotationsByType(NotNullValidate.class);
        Controller controller = inv.getController();
        if (ArrayUtil.isNotEmpty(validates)) {
            if (HttpEnum.PARA.equals(validates[0].type())) {
                for (NotNullValidate validate : validates) {
                    if (controller.getPara(validate.value()) == null) {
                        controller.renderJson(R.error(500, validate.message()));
                        return false;
                    }
                }
            } else if (HttpEnum.JSON.equals(validates[0].type())) {
                JSONObject jsonObject = JSON.parseObject(controller.getRawData());
                for (NotNullValidate validate : validates) {
                    if (!jsonObject.containsKey(validate.value()) || jsonObject.get(validate.value()) == null) {
                        controller.renderJson(R.error(500, validate.message()));
                        return false;
                    }
                }
            }
        }
        return true;
    }

    @SuppressWarnings("unchecked")
    private void modelToJson(Invocation inv) {
        Parameter[] parameters = inv.getMethod().getParameters();
        JSONObject jsonObject = null;
        for (int i = 0; i < parameters.length; i++) {
            if (parameters[i].getAnnotation(RequestBody.class) != null) {
                if (jsonObject == null) {
                    jsonObject = JSON.parseObject(inv.getController().getRawData());
                }
                //TODO 目前的处理是直接对整个json数据进行初始化
                Class clazz = parameters[i].getType();
                if (clazz.isAssignableFrom(Record.class)) {
                    inv.setArg(i, new Record().setColumns(jsonObject));
                } else if (BasicType.unWrap(clazz).isPrimitive() || clazz.isAssignableFrom(String.class) || clazz.isAssignableFrom(Date.class)) {
                    String name = parameters[i].getName();
                    inv.setArg(i, jsonObject.getObject(name, clazz));
                } else {
                    inv.setArg(i, jsonObject.toJavaObject(clazz));
                }
            }
        }
    }
}
